

#include "commmsg.h"
#include "../mainctrl.h"
#include "../cmd/dataprepare.h"
#include "cmdmount.h"

CT_REGISTER_ASYNCCMD(ID_MAIN_MOUNT_OPT, CCmdMountOpt);
int CCmdMountOpt::Do(void* pData)
{
    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_MOUNT_OPT ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_MOUNT_OPT,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    //检查登录
    _uiGID = stReq.gid();
    iRet = pstMainCtrl->CheckLogin(_uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdMountOpt::LogicDo(int iRet)
{
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, _uiGID);
    PREPARE_PLAYER_DETAIL_EX1_INFO(this, _uiGID);
    PREPARE_PLAYER_ONLINE_DATA(this, _uiGID);

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user player base info error, uid = %u", _uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerOnlineData & stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    if (!pstMainCtrl->m_stCommConfigLoader.IsOpen(SYS_OPEN_COND_ID_25, stPlayerBaseInfo, stPlayerOnlineData))
    {
        return AnsClients(ERROR_SYS_NOT_OPEN);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", _uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerDetailInfoEx1 & stPlayerDetailEx1 = pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

    CMountData & stMountData = stPlayerDetailEx1._stMount;
    bool bNeedSaveBaseInfo  = false;
    bool bNeedSaveDetailInfo = true;
    unsigned int uiNotify = 0;
    unsigned int uiNotifyPara = 0;
    switch (stReq.opt())
    {
    case 1:    //获取用户的坐骑信息
        {
            bNeedSaveDetailInfo = false;
        }
        break;

    case 2:   //骑乘坐骑
        {
            iRet = pstMainCtrl->m_stMountMgr.RideMount(stMountData, stReq.mount_id());
            if (RET_OK == iRet)
            {
                uiNotify |= (NOTIFY_MAP_INFO | NOTIFY_PARTNER_ATTR | NOTIFY_ROLE_ATTR);
                uiNotifyPara |= MAX_PARTNER_IN_MATRIX_FLAG;
            }
        }
        break;

    case 3: //坐骑升级
        {
            iRet = pstMainCtrl->m_stMountMgr.UpgradeMount(stPlayerBaseInfo._uiGID, stMountData, stReq.mount_id(), stReq.para());
            if (RET_OK == iRet)
            {
                uiNotify = (NOTIFY_PARTNER_ATTR | NOTIFY_ROLE_ATTR);
                uiNotifyPara |= MAX_PARTNER_IN_MATRIX_FLAG;
            }            
        }
        break;

    case 4:  //兑换坐骑
        {
            iRet = pstMainCtrl->m_stMountMgr.ExChangeMount(stPlayerBaseInfo._uiGID, stMountData, stReq.mount_id());
        }
        break;

    case 5:   //取消骑乘
        {
            iRet = pstMainCtrl->m_stMountMgr.UnRideMount(stMountData);
            if (RET_OK == iRet)
            {
                uiNotify |= (NOTIFY_MAP_INFO | NOTIFY_PARTNER_ATTR | NOTIFY_ROLE_ATTR);
                uiNotifyPara |= MAX_PARTNER_IN_MATRIX_FLAG;
            }
        }
        break;

    case 6:   //放弃
        {
            iRet = pstMainCtrl->m_stMountMgr.DiscardMount (stMountData, stReq.mount_id());
        }
        break;

    case 7:  //转化
        {
            iRet = pstMainCtrl->m_stMountMgr.TransMount(stMountData, stReq.mount_id());
        }
        break;

    case 8:  //猎魂
        {
            iRet = pstMainCtrl->m_stMountMgr.HuntSoul(_uiGID, stMountData, stReq.para(), stAns);
            if (iRet == iRet)
            {
                bNeedSaveBaseInfo = true;
                uiNotify |= NOTIFY_USER_MONEY;

                //触发任务
                pstMainCtrl->m_stTaskMgr.TriggerDoSomeOpt(stPlayerOnlineData._stUserTask, TASK_OPT_ID_134, 1);
            }
        }
        break;

    case 9:  //解锁格子位
        {
            iRet = pstMainCtrl->m_stMountMgr.UnlockPos(stPlayerBaseInfo, stMountData);
            if (iRet == iRet)
            {
                bNeedSaveBaseInfo = true;
                uiNotify |= NOTIFY_USER_MONEY;
            }
        }
        break;

    default:
        return AnsClients(ERROR_MOUNT_PARA);
    }

    if (iRet)
    {
        return AnsClients(iRet);
    }

    //更新坐骑的数据到online结构中
    pstMainCtrl->m_stMountMgr.InitData(stPlayerOnlineData,  stMountData);
    pstMainCtrl->m_stMountMgr.GetMountInfo (stMountData, stAns);

    //保存数据
    if (bNeedSaveBaseInfo)
    {
        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_BASE_INFO;
        stKey.m_u64ID = stPlayerBaseInfo._uiGID;
        CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerBaseInfo, VOP_UPDATE);
    }

    if (bNeedSaveDetailInfo)
    {
        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_DETAIL_EX1_INFO;
        stKey.m_u64ID = stPlayerDetailEx1._uiGID;
        CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerDetailEx1, VOP_UPDATE);
    }
        
    pstMainCtrl->m_stNotifyMgr.Notify(stPlayerBaseInfo._uiGID, uiNotify, uiNotifyPara);

    return AnsClients(RET_OK);
}

int CCmdMountOpt::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    stAns.set_opt(stReq.opt());
    stAns.set_mount_id(stReq.mount_id());
    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}
